home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / ACK3D.ZIP / ENGINE / ACKUTIL.C < prev    next >
Text File  |  1993-08-23  |  10KB  |  415 lines

  1. /******************* ( Animation Construction Kit 3D ) ***********************/
  2. /*                Utility Routines                     */
  3. /* CopyRight (c) 1993       Author: Lary Myers                     */
  4. /*****************************************************************************/
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <dos.h>
  9. #include <mem.h>
  10. #include <alloc.h>
  11. #include <io.h>
  12. #include <fcntl.h>
  13. #include <time.h>
  14. #include <string.h>
  15. #include <sys\stat.h>
  16. #include "ack3d.h"
  17. #include "ackeng.h"
  18. #include "ackext.h"
  19. #include "xmslib.h"
  20.  
  21. #define XMS_LOWVALUE    0x0280
  22. #define XMS_HIVALUE    0xA000
  23.  
  24. /****************************************************************************
  25. ** Return the square root of a long value                   **
  26. ****************************************************************************/
  27. long long_sqrt(long v)
  28. {
  29.     int        i;
  30.     unsigned    long result,tmp;
  31.     unsigned    long low,high;
  32.  
  33. if (v <= 1L) return((unsigned)v);
  34.  
  35. low = v;
  36. high = 0L;
  37. result = 0;
  38.  
  39. for (i = 0; i < 16; i++)
  40.     {
  41.     result += result;
  42.     high = (high << 2) | ((low >>30) & 0x3);
  43.     low <<= 2;
  44.  
  45.     tmp = result + result + 1;
  46.     if (high >= tmp)
  47.     {
  48.     result++;
  49.     high -= tmp;
  50.     }
  51.     }
  52.  
  53. if (v - (result * result) >= (result - 1))
  54.     result++;
  55.  
  56. return(result);
  57. }
  58.  
  59.  
  60. /****************************************************************************
  61. ** The application can use this routine to read in a 768 byte palette       **
  62. ** file and immediately set it in the video. PalName is the name of the       **
  63. ** palette file to load.                           **
  64. **                                       **
  65. ****************************************************************************/
  66. int AckLoadAndSetPalette(char *PalName)
  67. {
  68.     int        handle,ErrCode;
  69.     char    *buf;
  70.  
  71. buf = malloc(800);
  72. if (buf == NULL)
  73.     return(ERR_NOMEMORY);
  74.  
  75. ErrCode = 0;
  76. handle = open(PalName,O_RDWR|O_BINARY);
  77. if (handle > 0)
  78.     {
  79.     read(handle,buf,768);
  80.     close(handle);
  81.     AckSetPalette(buf);
  82.     }
  83. else
  84.     ErrCode = ERR_BADFILE;
  85.  
  86. free(buf);
  87. return(ErrCode);
  88. }
  89.  
  90. /****************************************************************************
  91. ** The application calls this routine to get the last object hit (from the **
  92. ** AckMovePOV() or AckMoveObjectPOV() routines.                   **
  93. **                                       **
  94. ****************************************************************************/
  95. int AckGetObjectHit(void)
  96. {
  97.  
  98. return(LastObjectHit);
  99. }
  100.  
  101. /****************************************************************************
  102. ** The application calls this routine to get the last wall hit (from the   **
  103. ** AckMovePOV() or AckMoveObjectPOV() routines.                   **
  104. **                                       **
  105. ****************************************************************************/
  106. int AckGetWallHit(void)
  107. {
  108.  
  109. return(LastMapPosn);
  110. }
  111.  
  112.  
  113. /****************************************************************************
  114. ** The application calls this routine to make an object invisible. The       **
  115. ** object and object bitmaps are NOT deleted. Currently the active flag       **
  116. ** is set to zero however, future versions may do more in the routine so   **
  117. ** it would be a good idea for the application to call here instead of       **
  118. ** setting the active flag to zero on its own.                   **
  119. **                                       **
  120. ****************************************************************************/
  121. int AckDeleteObject(ACKENG *ae,int ObjIndex)
  122. {
  123.     int        MapPosn;
  124.  
  125.  
  126. if (!ae->ObjList[ObjIndex].Active)
  127.     return(-1);
  128.  
  129. ae->ObjList[ObjIndex].Active = 0;
  130.  
  131. return(0);
  132. }
  133.  
  134. /****************************************************************************
  135. ** The purpose of this routine is to replace an existing bitmap with a       **
  136. ** new one. The old bitmap is freed and the new one is put into place in   **
  137. ** the specified bitmap array.                           **
  138. **                                       **
  139. ** index is the number of the bitmap array to replace               **
  140. ** Maps is the bitmap array                           **
  141. ** NewBitmap is a pointer to the new bitmap to use               **
  142. **                                       **
  143. ****************************************************************************/
  144. int AckSetNewBitmap(int index,UCHAR far **Maps,UCHAR far *NewBitmap)
  145. {
  146.     int            i;
  147.     UCHAR   far        *bPtr;
  148.  
  149. bPtr = Maps[index];
  150. if (FP_SEG(bPtr) < XMS_HIVALUE && FP_SEG(bPtr) > XMS_LOWVALUE)
  151.     {
  152.     if (bPtr == NewBitmap)
  153.     return(0);
  154.  
  155.     free(bPtr);
  156.     Maps[index] = NewBitmap;
  157.     return(0);
  158.     }
  159.  
  160. #if USE_XMS
  161.     XMSput((XMSHANDLE)bPtr,NewBitmap,BITMAP_SIZE);
  162.  
  163.     for (i = 0; i < MAX_XARRAY; i++)
  164.     {
  165.     if (bPtr == (UCHAR far *)xArray[i].xHandle)
  166.         {
  167.         memmove(xArray[i].Bmp,NewBitmap,BITMAP_SIZE);
  168.         }
  169.     }
  170. #endif
  171.  
  172. return(0);
  173. }
  174.  
  175.  
  176. /****************************************************************************
  177. ** This routine should be called for all wall and object bitmaps when using**
  178. ** XMS memory. It will copy the bitmap from XMS to a real memory array       **
  179. ** buffer which is then passed back to the caller. It checks for a buffer  **
  180. ** that has the smallest usage count (an empty one would have zero), to       **
  181. ** copy the XMS memory into. XMS handles have been observed to have a seg  **
  182. ** value of > A000H or < 100H (which hopefully will be true all the time!) **
  183. ****************************************************************************/
  184. UCHAR far *AckGetBitmapPtr(int index,UCHAR far **Maps)
  185. {
  186.     int        i,min,Lasti;
  187.     UCHAR   far *bPtr;
  188.  
  189. bPtr = Maps[index];
  190.  
  191. #if USE_XMS
  192.     if (FP_SEG(bPtr) < XMS_HIVALUE && FP_SEG(bPtr) > XMS_LOWVALUE)
  193.     return(bPtr);
  194.  
  195.     min = 32000;
  196.     Lasti = -1;
  197.  
  198.     for (i = 0; i < MAX_XARRAY; i++)
  199.     {
  200.     if (bPtr == (UCHAR far *)xArray[i].xHandle)
  201.         {
  202.         xArray[i].count++;
  203.         return(xArray[i].Bmp);
  204.         }
  205.  
  206.     if (xArray[i].count < min)
  207.         {
  208.         min = xArray[i].count;
  209.         Lasti = i;
  210.         }
  211.     }
  212.  
  213.     if (Lasti == -1)
  214.     {
  215.     XMSget(BitmapXferPtr,(XMSHANDLE)bPtr);
  216.     return(BitmapXferPtr);
  217.     }
  218.  
  219.     XMSget(xArray[Lasti].Bmp,(XMSHANDLE)bPtr);
  220.     xArray[Lasti].count = 1;
  221.     xArray[Lasti].xHandle = (ULONG)bPtr;
  222.  
  223.     return(xArray[Lasti].Bmp);
  224. #else
  225.     return(bPtr);
  226. #endif
  227. }
  228.  
  229.  
  230. #define LOCK_MAX    20
  231.  
  232. typedef struct {
  233.     XMSHANDLE    xHandle;
  234.     UCHAR   far *Bmp;
  235. } LOCKLIST;
  236.  
  237.  
  238.     LOCKLIST     LockTable[LOCK_MAX+1];
  239.  
  240.  
  241. /****************************************************************************
  242. ** This routine loads an XMS bitmap into memory for use by the app. If the **
  243. ** bitmap is not in XMS then the bitmap pointer itself is returned.       **
  244. **                                       **
  245. ****************************************************************************/
  246. UCHAR far *AckLockPtr(UCHAR far *bPtr)
  247. {
  248.     int        i,uFlag;
  249.     UCHAR   far *bmp;
  250.  
  251.  
  252. #if USE_XMS
  253.     uFlag = 0;
  254.  
  255.     if (FP_SEG(bPtr) < XMS_HIVALUE && FP_SEG(bPtr) > XMS_LOWVALUE)
  256.     return(bPtr);
  257.  
  258.     bmp = malloc(BITMAP_SIZE);
  259.     if (bmp == NULL)
  260.     return(bmp);
  261.  
  262.     XMSget(bmp,(XMSHANDLE)bPtr);
  263.  
  264.     for (i = 0; i < LOCK_MAX; i++)
  265.     {
  266.     if (LockTable[i].Bmp == NULL)
  267.         {
  268.         LockTable[i].Bmp = bmp;
  269.         LockTable[i].xHandle = (XMSHANDLE)bPtr;
  270.         uFlag = 1;
  271.         break;
  272.         }
  273.     }
  274.  
  275.     if (!uFlag)
  276.     {
  277.     LockTable[0].Bmp = bmp;
  278.     LockTable[0].xHandle = (XMSHANDLE)bPtr;
  279.     }
  280.     return(bmp);
  281. #else
  282.     return(bPtr);
  283. #endif
  284.  
  285. }
  286.  
  287.  
  288. /****************************************************************************
  289. ** This routine frees up a previously locked pointer. If the pointer is       **
  290. ** not in XMS then no action is taken.                       **
  291. **                                       **
  292. ****************************************************************************/
  293. int AckUnlockPtr(UCHAR far *bPtr)
  294. {
  295.     int        i,j;
  296.  
  297.  
  298. #if USE_XMS
  299.  
  300.     for (i = 0; i < LOCK_MAX; i++)
  301.     {
  302.     if (LockTable[i].Bmp == bPtr)
  303.         {
  304.         XMSput(LockTable[i].xHandle,bPtr,BITMAP_SIZE);
  305.  
  306.         for (j = 0; j < MAX_XARRAY; j++)
  307.         {
  308.         if (xArray[j].xHandle == LockTable[i].xHandle)
  309.             {
  310.             memmove(xArray[j].Bmp,bPtr,BITMAP_SIZE);
  311.             break;
  312.             }
  313.         }
  314.  
  315.         free(LockTable[i].Bmp);
  316.         LockTable[i].Bmp = NULL;
  317.         return(0);
  318.         }
  319.     }
  320.  
  321.     return(-1);
  322. #else
  323.     return(0);
  324. #endif
  325. }
  326.  
  327.  
  328. /****************************************************************************
  329. ** This routine creates a new bitmap buffer (in real or XMS memory) and       **
  330. ** copies the supplied bitmap into it. The return pointer is either an       **
  331. ** XMS handle or a pointer to the real memory.                   **
  332. **                                       **
  333. ****************************************************************************/
  334. UCHAR far *AckCopyNewBitmap(UCHAR far *bPtr)
  335. {
  336.     UCHAR   far        *bmp;
  337. #if USE_XMS
  338.     XMSHANDLE        xPtr;
  339.  
  340.     if (UseXMS > 0)
  341.     {
  342.     xPtr = XMSalloc(BITMAP_SIZE);
  343.     if (xPtr != XMSHNULL)
  344.         {
  345.         if (FP_SEG(bPtr) > XMS_HIVALUE || FP_SEG(bPtr) < XMS_LOWVALUE)
  346.         XMSget(BitmapXferPtr,(XMSHANDLE)bPtr);
  347.         else
  348.         memmove(BitmapXferPtr,bPtr,BITMAP_SIZE);
  349.  
  350.         XMSput(xPtr,BitmapXferPtr,BITMAP_SIZE);
  351.         return((UCHAR far *)xPtr);
  352.         }
  353.     else
  354.         {
  355.         bmp = malloc(BITMAP_SIZE);
  356.         if (bmp)
  357.         memmove(bmp,bPtr,BITMAP_SIZE);
  358.         return(bmp);
  359.         }
  360.  
  361.     }
  362.     else
  363.     {
  364.     bmp = malloc(BITMAP_SIZE);
  365.     if (bmp)
  366.         memmove(bmp,bPtr,BITMAP_SIZE);
  367.     return(bmp);
  368.     }
  369. #else
  370.     bmp = malloc(BITMAP_SIZE);
  371.     if (bmp)
  372.     memmove(bmp,bPtr,BITMAP_SIZE);
  373.     return(bmp);
  374. #endif
  375.  
  376. }
  377.  
  378. /****************************************************************************
  379. ** This routine frees the memory used by a bitmap in either real or XMS       **
  380. ** memory.                                   **
  381. **                                       **
  382. ****************************************************************************/
  383. int AckFreeBitmap(UCHAR far *Bmp)
  384. {
  385.     int    i;
  386.  
  387. #if USE_XMS
  388.  
  389.     if (FP_SEG(Bmp) > XMS_HIVALUE || FP_SEG(Bmp) < XMS_LOWVALUE)
  390.     {
  391.     for (i = 0; i < MAX_XARRAY; i++)
  392.         {
  393.         if (xArray[i].xHandle == (XMSHANDLE)Bmp)
  394.         {
  395.         xArray[i].count = 0;
  396.         xArray[i].Bmp = XMSHNULL;
  397.         break;
  398.         }
  399.  
  400.         }
  401.  
  402.     XMSfree((XMSHANDLE)Bmp);
  403.  
  404.     }
  405.     else
  406.     free(Bmp);
  407.  
  408. #else
  409.     free(Bmp);
  410. #endif
  411.  
  412. return(0);
  413. }
  414.  
  415.